package com.cayden.config.project.componets.aop;

import com.cayden.componets.aop.factory.AopContain;
import com.cayden.config.project.componets.annotation.Master;
import com.cayden.config.project.componets.annotation.Slave;
import com.cayden.config.project.componets.db.DynamicDataSourceHolder;
import com.cayden.config.project.componets.db.MultipleDataSourcesProperties;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.annotation.Order;

import java.lang.reflect.Method;

/**
 * Created with IntelliJ IDEA.
 *
 * @author: cayden
 * Date: 2021/9/27 22:10
 */
@Aspect
@Order(value = -2100000000)
@ConditionalOnProperty(value = "cayden.multiple.enable",havingValue = "true")
public class CheckDataSourceHandleAop implements AopContain {

    @Autowired
    private MultipleDataSourcesProperties multipleDataSourcesProperties;

    @Around(value = "@annotation(org.springframework.transaction.annotation.Transactional) || " +
            "@annotation(com.cayden.config.project.componets.annotation.Master) || " +
            "@annotation(com.cayden.config.project.componets.annotation.Slave)")
    @Override
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        Signature signature = pjp.getSignature();
        MethodSignature ms = (MethodSignature) signature;
        Method method = ms.getMethod();
        Master master = method.getAnnotation(Master.class);
        Slave slave = method.getAnnotation(Slave.class);

        if (multipleDataSourcesProperties.getEnable() && master != null && slave == null){
            DynamicDataSourceHolder.chooseMaster();
            Object result = pjp.proceed();
            // 对于切换主数据源来说，使用了应该切换回去从库
            DynamicDataSourceHolder.chooseSlave();
            return result;
        }

        if (slave != null && master == null){
            if (slave.value() == 0){
                DynamicDataSourceHolder.chooseSlave();
            }else{
                DynamicDataSourceHolder.chooseSlave(slave.value());
            }
        }

        return pjp.proceed();
    }
}
